//
//  YXPlayerDownloadSessionManger.swift
//  swift_wobo
//
//  Created by yuxin on 2018/12/3.
//  Copyright © 2018 wuxiantianli. All rights reserved.
//

import UIKit

protocol YXPlayerDownloadSessionMangerDelegate: class {
    
    func yx_urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void)
    func yx_urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse, completionHandler: @escaping (URLSession.ResponseDisposition) -> Swift.Void)
    func yx_urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data)
    func yx_urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?)
    
}
class YXPlayerDownloadSessionManger: NSObject {
    private let kBufferSize = 10 * 1024
    private let bufferData = NSMutableData()
    private let bufferDataQueue = DispatchQueue(label: "com.YXplayer.bufferDataQueue")
    
    weak var delegate: YXPlayerDownloadSessionMangerDelegate?
    
    init(delegate: YXPlayerDownloadSessionMangerDelegate) {
        self.delegate = delegate
        super.init()
    }
}

extension YXPlayerDownloadSessionManger: URLSessionDelegate {
    
    func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
        delegate?.yx_urlSession(session, didReceive: challenge, completionHandler: completionHandler)
    }
    
    func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse, completionHandler: @escaping (URLSession.ResponseDisposition) -> Swift.Void) {
        delegate?.yx_urlSession(session, dataTask: dataTask, didReceive: response, completionHandler: completionHandler)
    }
    
    func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
        bufferDataQueue.sync {
            bufferData.append(data)
            if self.bufferData.length > kBufferSize {
                let chunkRange = NSRange(location: 0, length: self.bufferData.length)
                let chunkData = bufferData.subdata(with: chunkRange)
                bufferData.replaceBytes(in: chunkRange, withBytes: nil, length: 0)
                delegate?.yx_urlSession(session, dataTask: dataTask, didReceive: chunkData)
            }
        }
    }
    
    func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
        bufferDataQueue.sync {
            if bufferData.length > 0 && error == nil {
                let chunkRange = NSRange(location: 0, length: bufferData.length)
                let chunkData = bufferData.subdata(with: chunkRange)
                bufferData.replaceBytes(in: chunkRange, withBytes: nil, length: 0)
                delegate?.yx_urlSession(session, dataTask: (task as! URLSessionDataTask), didReceive: chunkData)
            }
        }
        delegate?.yx_urlSession(session, task: task, didCompleteWithError: error)
    }
}
